package com.huijy.web.controller.api;

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.huijy.common.annotation.LoginMember;
import com.huijy.common.annotation.UnLogin;
import com.huijy.common.config.RuoYiConfig;
import com.huijy.common.core.domain.AjaxResult;
import com.huijy.common.core.domain.entity.SysDictData;
import com.huijy.common.core.page.TableDataInfo;
import com.huijy.common.exception.ServiceException;
import com.huijy.common.utils.SendSms;
import com.huijy.common.utils.StringUtils;
import com.huijy.common.utils.file.FileUploadUtils;
import com.huijy.framework.config.ServerConfig;
import com.huijy.management.domain.*;
import com.huijy.management.service.*;
import com.huijy.management.vo.WxPhoneFrom;
import com.huijy.system.service.ISysDictDataService;
import com.huijy.weixin.config.WxMaConfiguration;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import springfox.documentation.annotations.ApiIgnore;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(value = "小程序", tags = "小程序接口")
@RestController
@RequestMapping("/api/index")
public class ApiIndexController extends ApiAbstractController {

    @Autowired
    private IMemberService memberService;
    @Autowired
    private IMemberLocationService memberLocationService;
    @Autowired
    private IAboutUsService aboutUsService;
    @Autowired
    private IContentService contentService;
    @Autowired
    private IShopService shopService;
    @Autowired
    private IShopSalesRecordService shopSalesRecordService;
    @Autowired
    private ISysDictDataService sysDictDataService;
    @Autowired
    private IMarkerService markerService;
    @Autowired
    private IEarlyWarningService earlyWarningService;
    @Autowired
    private IMemberHelpService memberHelpService;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private IShopRoomService roomService;

    @Autowired
    private IShopRoomOrderService orderService;

    @Autowired
    private IFeedbackService feedbackService;

    //绑定手机号
    @PostMapping("/bindMobile")
    @ApiOperation("绑定会员手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "会员手机号", paramType = "body")
    })
    public AjaxResult bindMobile(@ApiIgnore @LoginMember Member member, @RequestBody Map params) {

        String phone = (String) params.get("phone");
        member.setMobile(phone);
        memberService.updateMember(member);
        return AjaxResult.success();
    }

    //绑定微信手机号
    @PostMapping("/bindWxMobile")
    @ApiOperation("绑定会员微信手机号")
    public AjaxResult bindWxMobile(@ApiIgnore @LoginMember Member member, @RequestBody WxPhoneFrom wxPhoneFrom) {

        if (null == wxPhoneFrom) {
            return AjaxResult.error("无加密信息");
        }
        //验证code
        if (StringUtils.isEmpty(wxPhoneFrom.getCode())) {
            return AjaxResult.error("code不能为空");
        }
        //获取sessionKey
        String token, sessionKey, openId, unionId;
        try {
            WxMaJscode2SessionResult result = WxMaConfiguration.getMaService().getUserService().getSessionInfo(wxPhoneFrom.getCode());
            unionId = result.getUnionid();
            sessionKey = result.getSessionKey();
            openId = result.getOpenid();
        } catch (WxErrorException e) {
            e.printStackTrace();
            throw new ServiceException("sessionKey获取失败");
        }

        //解密码
        WxMaPhoneNumberInfo phoneNumberInfo = WxMaConfiguration.getMaService().getUserService().getPhoneNoInfo(sessionKey, wxPhoneFrom.getEncryptedData(), wxPhoneFrom.getIv());
        if (phoneNumberInfo == null) {
            return AjaxResult.error("获取手机号码失败");
        }
        member.setMobile(phoneNumberInfo.getPhoneNumber());
        memberService.updateMember(member);
        return AjaxResult.success(member);
    }


    @PostMapping("/pushLatLng")
    @ApiOperation("上传会员坐标")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "lat", value = "坐标的lat", paramType = "body"),
            @ApiImplicitParam(name = "lng", value = "坐标的lng", paramType = "body")
    })
    public AjaxResult pushLatLng(@ApiIgnore @LoginMember Member member, @RequestBody Map params) {

        String lat = (String) params.get("lat");
        String lng = (String) params.get("lng");


        member.setLastLat(lat);
        member.setLastLng(lng);
        memberService.updateMember(member);
        MemberLocation location = new MemberLocation();
        location.setLat(lat);
        location.setLng(lng);
        location.setMemberId(member.getMemberId());


        memberLocationService.insertMemberLocation(location);
        return AjaxResult.success();
    }

    //图片上传请求
    @ApiOperation("图片上传请求")
    @PostMapping("/uploadImg")
    public AjaxResult uploadFile(MultipartHttpServletRequest multiReq) {
        try {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, multiReq.getFile("img"));
            String url = serverConfig.getUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("fileName", fileName);
            ajax.put("url", url);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    //上传会员拨打记录
    @PostMapping("/pushHelp")
    @ApiOperation("上传会员拨打记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "lat", value = "坐标的lat", dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "lng", value = "坐标的lng", dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "phone", value = "求助电话", dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "memberPhone", value = "会员电话", dataType = "String", paramType = "body"),
    })
    public AjaxResult pushHelp(@ApiIgnore @LoginMember Member member, @RequestBody MemberHelp help) {
        help.setMemberId(member.getMemberId());
        if (StringUtils.isEmpty(help.getMemberPhone())) {
            help.setMemberPhone(member.getMobile());
        }
        memberHelpService.insertMemberHelp(help);
        return AjaxResult.success();
    }

    @GetMapping("/getPageContent")
    @ApiOperation("分页获取主要内容信息")
    @UnLogin
    public TableDataInfo getPageContent(Content content) {
        content.setReleaseFlag("1");
        startPage();
        List<Content> list = contentService.selectContentList(content);
        return getDataTable(list);
    }

    @GetMapping("/getContentInfo/{contentId}")
    @ApiOperation("获取主要内容详细信息")
    @UnLogin
    public AjaxResult getContentInfo(@PathVariable Integer contentId) {
        Content info = contentService.selectContentByContentId(contentId.longValue());
        Map<String, Object> resultObj = new HashMap<String, Object>();
        resultObj.put("info", info);
        return AjaxResult.success(resultObj);

    }

    //门店开通申请
    @PostMapping("/shopApply")
    @ApiOperation("商铺开通申请")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "商铺名称", required = true, paramType = "body"),
            @ApiImplicitParam(name = "addres", value = "地址", paramType = "body"),
            @ApiImplicitParam(name = "bossName", value = "老板名称", required = true, paramType = "body"),
            @ApiImplicitParam(name = "bossPhone", value = "老板电话", required = true, paramType = "body"),
            @ApiImplicitParam(name = "businessHours", value = "营业时间", paramType = "body"),
            @ApiImplicitParam(name = "briefContent", value = "简介", paramType = "body"),
            @ApiImplicitParam(name = "lat", value = "坐标的lat", paramType = "body"),
            @ApiImplicitParam(name = "lng", value = "坐标的lng", paramType = "body"),
            @ApiImplicitParam(name = "shopType", value = "商铺类型 1、商铺 2、酒店", defaultValue = "1", paramType = "body"),
    })
    public AjaxResult storeApply(@ApiIgnore @LoginMember Member member, @RequestBody Shop shop) {
        if (shop == null) {
            AjaxResult.error("提交数据为空");
        }
        shop.setAuditFlag("0");
        shop.setEnableFlag("0");
        shopService.insertShop(shop);
        return AjaxResult.success();
    }

    //门店开通申请
    @GetMapping("/getShopList")
    @ApiOperation("获取商铺列表")
    public AjaxResult getShopList(@ApiIgnore @LoginMember Member member) {
        List list = shopService.getListByMemberId(member.getMemberId());
        Map<String, Object> resultObj = new HashMap<String, Object>();
        resultObj.put("list", list);
        return AjaxResult.success(resultObj);
    }

    @GetMapping("/getShopInfo/{shopId}")
    @ApiOperation("获取商铺列表")
    public AjaxResult getShopInfo(@ApiIgnore @LoginMember Member member, @PathVariable Long shopId) {
        if (shopId == null) {
            return AjaxResult.error("提交数据为空");
        }
        Shop shop = shopService.selectShopByShopId(shopId);
        Map<String, Object> resultObj = new HashMap<String, Object>();
        resultObj.put("shopInfo", shop);
        return AjaxResult.success(resultObj);
    }

    //更新门店信息
    @PostMapping("/updateShop")
    @ApiOperation("未审核时，允许更新门店信息")
    public AjaxResult updateShop(@RequestBody Shop shop) {
        if (shop.getShopId() == null) {
            return AjaxResult.error("提交数据为空");
        }
        //未审核时才允许更新门店信息
        if (shop.getAuditFlag().equals("0") || shop.getAuditFlag().equals("2")) {
            //审核不通过重新提交材料，把审核状态改为待审核
            if (shop.getAuditFlag().equals("2")) {
                shop.setAuditFlag("0");
            }
            shopService.updateShop(shop);
            return AjaxResult.success();
        }
        return AjaxResult.error("店铺信息不允许更新");
    }

    //是否开启酒店预订
    @GetMapping("/hotelEnable")
    @ApiOperation("是否开启酒店预订")
    public AjaxResult hotelEnable(Long shopId, String enableFlag) {
        Shop shop = new Shop();
        shop.setShopId(shopId);
        shop.setEnableFlag(enableFlag);
        return AjaxResult.success(shopService.updateShop(shop));
    }

    //注销并且关闭店铺(物理删除)
    @GetMapping("/hotelDelete")
    @ApiOperation("注销并且关闭店铺")
    public AjaxResult hotelDelete(Long shopId) {
        return AjaxResult.success(shopService.deleteShopByShopId(shopId));
    }

    //门店数据上报
    @PostMapping("/pushRecord")
    @ApiOperation("门店数据上报")
    @Transactional
    public AjaxResult storeApply(@ApiIgnore @LoginMember Member member, @RequestBody ShopSalesRecord shopSalesRecord) {
        if (shopSalesRecord == null) {
            AjaxResult.error("上传数据为空");
        }
        shopSalesRecordService.insertShopSalesRecord(shopSalesRecord);
        return AjaxResult.success();
    }

    //获取酒店房间
    @GetMapping("/roomList")
    @ApiOperation("获取酒店房间")
    public AjaxResult getRoom(@RequestParam Long shopId) {
        List<ShopRoom> list = roomService.selectShopRoomByShopId(shopId);
        return AjaxResult.success(list);
    }

    //商家添加酒店房间
    @PostMapping("/roomAdd")
    @ApiOperation("商家添加酒店房间")
    public AjaxResult roomAdd(@RequestBody ShopRoom room) {
        if (room.getId() == null) {
            return AjaxResult.success(roomService.insertShopRoom(room));
        } else {
            return AjaxResult.success(roomService.updateShopRoom(room));
        }
    }

    //酒店列表
    @UnLogin
    @GetMapping("/hotelList")
    @ApiOperation("酒店列表")
    public TableDataInfo hotelList(Shop shop) {
        startPage();
        List<Shop> list = shopService.selectShopByHotel(shop);
        return getDataTable(list);
    }

    //酒店详情
    @GetMapping("/shopManage")
    @ApiOperation("店铺管理")
    public AjaxResult shopManage(@LoginMember Member member, Long shopId) {
        AjaxResult result = new AjaxResult();
        Shop shop = shopService.selectShopByShopId(shopId);
        if (shop != null) {
            //商家未处理的预定订单
            ShopRoomOrder order = new ShopRoomOrder();
            order.setState(0);
            order.setMemberId(member.getMemberId());
            order.setRole("sale");
            List<ShopRoomOrder> orders = orderService.selectShopRoomOrder(order);
            result.put("orders", orders);
        }
        result.put("shop", shop);
        return AjaxResult.success(result);
    }

    //酒店详情
    @UnLogin
    @GetMapping("/hotelDetail")
    @ApiOperation("酒店详情")
    public AjaxResult hotelDetail(Long shopId) {
        Shop shop = shopService.selectShopByShopId(shopId);
        if (shop != null) {
            List<ShopRoom> list = roomService.selectShopRoomByShopId(shop.getShopId());
            shop.setRooms(list);
        }
        return AjaxResult.success(shop);
    }

    //首页数据
    @UnLogin
    @GetMapping("/home")
    @ApiOperation("首页数据")
    public AjaxResult home() {
        AjaxResult result = new AjaxResult();
        AboutUs aboutUs = aboutUsService.selectAboutUsByAboutUsId(1L);
        result.put("aboutUs", aboutUs);
        List<Content> hot_list = contentService.home("2"); //热门景区
        List<Content> zn_list = contentService.home("3"); //攻略指南
        result.put("hot_list", hot_list);
        result.put("zn_list", zn_list);
        return AjaxResult.success(result);
    }

    //酒店预订
    @PostMapping("/hotelBook")
    @ApiOperation("酒店预订")
    public AjaxResult hotelBook(@RequestBody ShopRoomOrder order) {
        return AjaxResult.success(orderService.insertShopRoomOrder(order));
    }

    //投诉建议
    @PostMapping("/feedback")
    @ApiOperation("投诉建议")
    public AjaxResult hotelBook(@RequestBody Feedback feedback) {
        return AjaxResult.success(feedbackService.insertFeedback(feedback));
    }

    @GetMapping("/order")
    @ApiOperation("酒店预订订单")
    public TableDataInfo order(@LoginMember Member member, ShopRoomOrder order) {
        if (order.getRole() == null) {
            return getDataTable(new ArrayList<>());
        }
        startPage();
        order.setMemberId(member.getMemberId());
        List<ShopRoomOrder> list = orderService.selectShopRoomOrder(order);
        return getDataTable(list);
    }

    //商家订单处理
    @PostMapping("/orderDeal")
    @ApiOperation("商家订单处理")
    public AjaxResult orderDeal(@RequestBody ShopRoomOrder order) {
        order.setCreateTime(null);
        if (StringUtils.isEmpty(order.getMsg()) && order.getState() == 2) {
            order.setMsg("入住的时间段酒店客房已满,无法安排入住");
        }
        int row = orderService.updateShopRoomOrder(order);
        //发送小程序订阅消息
        if (row > 0 && order.getState() == 1) {
            sendMessage("酒店预订成功通知", order);
            SendSms.send(order.getPhone(), "1276086", order.getShopName(), order.getMin());
        }
        if (row > 0 && order.getState() == 2) {
            sendMessage("酒店预订失败通知", order);
            SendSms.send(order.getPhone(), "1276089", order.getShopName(), order.getMsg());
        }
        return AjaxResult.success(row);
    }

    //商家订单删除
    @GetMapping("/orderDelete")
    @ApiOperation("商家订单删除")
    public AjaxResult orderDelete(Long id) {
        return AjaxResult.success(orderService.deleteShopRoomOrderById(id));
    }

    //商家删除酒店房间
    @GetMapping("/roomDel")
    @ApiOperation("商家删除酒店房间")
    public AjaxResult roomDel(Long id) {
        return AjaxResult.success(roomService.deleteShopRoomById(id));
    }

    //返回标记物类型
    @PostMapping("/getMarkerType")
    @ApiOperation("获取标记物类型")
    public AjaxResult getMarkerDictData() {
        SysDictData dictData = new SysDictData();
        dictData.setDictType("marker_type");
        dictData.setStatus("0");
        List<SysDictData> list = sysDictDataService.selectDictDataList(dictData);
        Map<String, Object> resultObj = new HashMap<String, Object>();
        resultObj.put("list", list);
        return AjaxResult.success(resultObj);
    }

    //根据标记物类型分页获取标记物信息
    @GetMapping("/getPageMarker")
    @ApiOperation("根据标记物类型分页获取标记物信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "markerType", value = "标记物类型:0为所有类型", required = true, defaultValue = "0", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "pageNum", required = true, defaultValue = "1", value = "页码", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", required = true, defaultValue = "20", value = "显示记录数", paramType = "query")
    })
    public TableDataInfo getPageMarker(String markerType) {

        Marker marker = new Marker();
        if (StringUtils.isNotEmpty(markerType) && !markerType.equalsIgnoreCase("0")) {
            marker.setMarkerType(markerType);
        }
        startPage();
        List<Marker> list = markerService.selectMarkerList(marker);
        return getDataTable(list);

    }

    //根据contentId(景区id)获取标记物
    @GetMapping("/getMarkerList/{contentId}")
    @UnLogin
    @ApiOperation("根据contentId(景区id)获取标记物")
    public AjaxResult getPageMarker(@PathVariable Long contentId) {
        List<Marker> list = markerService.selectMarkerList(contentId);
        Map<String, Object> resultObj = new HashMap<String, Object>();
        resultObj.put("list", list);
        return AjaxResult.success(resultObj);

    }


    @PostMapping("/getEarlyWarnType")
    @ApiOperation("获取预警类型")
    public AjaxResult getEarlyWarnType() {
        SysDictData dictData = new SysDictData();
        dictData.setDictType("early_warning_type");
        dictData.setStatus("0");
        List<SysDictData> list = sysDictDataService.selectDictDataList(dictData);
        Map<String, Object> resultObj = new HashMap<String, Object>();
        resultObj.put("list", list);
        return AjaxResult.success(resultObj);
    }


    @GetMapping("/getPageEarlyWarn")
    @ApiOperation("根据预警类型分页获取预警信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "earlyWarnType", value = "预警类型:0为所有类型", required = true, defaultValue = "0", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "pageNum", required = true, defaultValue = "1", value = "页码", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", required = true, defaultValue = "20", value = "显示记录数", paramType = "query")
    })
    public TableDataInfo getPageEarlyWarn(String earlyWarnType) {

        EarlyWarning earlyWarning = new EarlyWarning();
        if (StringUtils.isNotEmpty(earlyWarnType) && !earlyWarnType.equalsIgnoreCase("0")) {
            earlyWarning.setEarlyWarningType(earlyWarnType);
        }
        startPage();
        List<EarlyWarning> list = earlyWarningService.selectEarlyWarningList(earlyWarning);
        return getDataTable(list);

    }

    //订阅消息
    private String sendMessage(String type, ShopRoomOrder order) {
        JSONObject jsonObject = JSONUtil.parseObj(HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + WxMaConfiguration.getMaService().getWxMaConfig().getAppid() + "&secret=" + WxMaConfiguration.getMaService().getWxMaConfig().getSecret()));
        JSONObject body = new JSONObject();
        body.set("touser", order.getOpenid());
        JSONObject content = new JSONObject();
        if (type.equals("酒店预订成功通知")) {
            body.set("template_id", "n8RXfziuC2B1UmBThhxNuo45QufO8xd5QepzghBfVJc");
            content.set("thing1", new JSONObject().set("value", order.getShopName()));
            content.set("thing4", new JSONObject().set("value", order.getAddres()));
            content.set("date5", new JSONObject().set("value", order.getMin()));
        }
        if (type.equals("酒店预订失败通知")) {
            body.set("template_id", "-7bgeC4AoVA-GHLmVCVnPB6Ja_1Tru54qsYnQK4baOE");
            content.set("thing5", new JSONObject().set("value", "预订" + order.getShopName() + order.getShopRoom().getTitle()));
            content.set("thing6", new JSONObject().set("value", order.getMsg()));
        }
        body.set("data", content);
        String result = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + jsonObject.getStr("access_token"), body.toString());
        System.out.println("订单信息：" + content.toString());
        System.out.println("订单信息：" + order.toString());
        System.out.println("小程序订阅消息：" + result);
        return result;
    }

}
